What is ember-cli-htmlbars?
The ember-cli-htmlbars package is an Ember CLI addon that provides a precompiler for Handlebars templates. It allows you to write Handlebars templates in your Ember.js applications and have them compiled into JavaScript functions that can be rendered efficiently.
What are ember-cli-htmlbars's main functionalities?
Precompiling Handlebars Templates
This feature allows you to precompile Handlebars templates into JavaScript functions. The `hbs` tagged template literal is used to define a Handlebars template, which is then compiled by ember-cli-htmlbars.
import { hbs } from 'ember-cli-htmlbars';
export default hbs`<div>{{yield}}</div>`;
Integration with Ember CLI
The package integrates seamlessly with Ember CLI, allowing you to easily add it to your Ember.js project using the Ember CLI command line tool.
ember install ember-cli-htmlbars
Template Compilation
This feature provides a function to compile Handlebars templates into JavaScript functions programmatically. The `compileTemplate` function takes a Handlebars template string and returns a compiled template function.
import { compileTemplate } from 'ember-cli-htmlbars';
const template = compileTemplate('<div>{{yield}}</div>');
Other packages similar to ember-cli-htmlbars
handlebars
The handlebars package is the core Handlebars library that provides the functionality to compile and render Handlebars templates. While it is not specific to Ember.js, it can be used in any JavaScript project to work with Handlebars templates.
ember-handlebars
The ember-handlebars package is an older package that was used in earlier versions of Ember.js to provide Handlebars template compilation. It has largely been replaced by ember-cli-htmlbars in modern Ember.js applications.
Ember CLI HTMLBars
Compatibility
- Ember.js v3.8 or above
- Ember CLI v3.8 or above
- Node.js v12 or above
Tagged Template Usage / Migrating from htmlbars-inline-precompile
Starting with version 4.0, this addon now includes the testing helper from ember-cli-htmlbars-inline-precompile
This will require an update to the imports of the hbs
helper in your tests:
Prior syntax:
import hbs from 'htmlbars-inline-precompile';
...
await render(hbs`
<MyComponent />
`);
New syntax:
import { hbs } from 'ember-cli-htmlbars';
...
await render(hbs`
<MyComponent />
`);
There is a codemod available to automate this change.
Additional Trees
For addons which want additional customizations, they are able to interact with
this addon directly.
interface EmberCLIHTMLBars {
transpileTree(inputTree: BroccoliTree): BroccoliTree;
}
transpileTree
usage
let htmlbarsAddon = this.addons.find(addon => addon.name === 'ember-cli-htmlbars');
let transpiledCustomTree = htmlbarsAddon.transpileTree(someCustomTree);
Adding Custom Plugins
You can add custom plugins to be used during transpilation of the addon/
or
addon-test-support/
trees of your addon (or the app/
and tests/
trees of an application)
by registering a custom AST transform.
var SomeTransform = require('./some-path/transform');
module.exports = {
name: 'my-addon-name',
included: function() {
this.app.registry.add('htmlbars-ast-plugin', {
name: 'some-transform',
plugin: SomeTransform
});
this._super.included.apply(this, arguments);
}
};
Options for registering a plugin
name
- String. The name of the AST transform for debugging purposes.plugin
- A function of type ASTPluginBuilder
.dependencyInvalidation
- Boolean. A flag that indicates the AST Plugin may, on a per-template basis, depend on other files that affect its output.cacheKey
- function that returns any JSON-compatible value - The value returned is used to invalidate the persistent cache across restarts, usually in the case of a dependency or configuration change.baseDir
- () => string
. A function that returns the directory on disk of the npm module for the plugin. If provided, a basic cache invalidation is performed if any of the dependencies change (e.g. due to a npm install/upgrade).
Implementing Dependency Invalidation in an AST Plugin
Plugins that set the dependencyInvalidation
option to true
can provide function for the plugin
of type ASTDependencyPlugin
as given below.
Note: the plugin
function is invoked without a value for this
in context.
import {ASTPluginBuilder, ASTPlugin} from "@glimmer/syntax/dist/types/lib/parser/tokenizer-event-handlers";
export type ASTDependencyPlugin = ASTPluginWithDepsBuilder | ASTPluginBuilderWithDeps;
export interface ASTPluginWithDepsBuilder {
(env: ASTPluginEnvironment): ASTPluginWithDeps;
}
export interface ASTPluginBuilderWithDeps extends ASTPluginBuilder {
dependencies(relativePath): string[];
}
export interface ASTPluginWithDeps extends ASTPlugin {
resetDependencies?(relativePath: string): void;
dependencies(relativePath: string): string[];
}
Precompile HTMLBars template strings within other addons
module.exports = {
name: 'my-addon-name',
setupPreprocessorRegistry: function(type, registry) {
var htmlbarsPlugin = registry.load('template').find(function(plugin) {
return plugin.name === 'ember-cli-htmlbars';
});
var precompiled = htmlbarsPlugin.precompile("{{my-component}}");
}
};
Custom Template Compiler
You can still provide a custom path to the template compiler (e.g. to test
custom template compiler tweaks in an application) by:
module.exports = function(defaults) {
let app = new EmberApp(defaults, {
'ember-cli-htmlbars': {
templateCompilerPath: `some_path/to/ember-template-compiler.js`,
}
});
};
Using as a Broccoli Plugin
var HtmlbarsCompiler = require('ember-cli-htmlbars');
var templateTree = new HtmlbarsCompiler('app/templates', {
isHTMLBars: true,
templateCompiler: require('./bower_components/ember/ember-template-compiler')
});